#include "MODBUSTCP_SLAVE.h"

MODBUSTCP_SLAVE_T* MODBUSTCP_SLAVE_t;
MODBUSTCP_SLAVE_List_Par_t MODBUSTCP_SLAVE_List_Par;

//************************************
// Method:    	MODBUSTCP_SLAVE_WORK		modbus-tcp从站工作函数
// Programmer:  lww
// Time:		2019/2/24
// Returns:   	void
//************************************
void CARD_WORK(MODBUSTCP_SLAVE)()
{
	pthread_t tMODBUSTCP_SLAVE_WORK_ID;
	THREAD_CREATE_FAILED(Thread_Create("tMODBUSTCP_SLAVE_WORK", &tMODBUSTCP_SLAVE_WORK_ID, NULL, SCHED_POLICY, 89, true, tMODBUSTCP_SLAVE_WORK, CONTROL_CORE, NULL));
}

//************************************
// Method:    	tMODBUSTCP_SLAVE_WORK		modbus-tcp从站工作线程
// Programmer:  lww
// Time:		2019/7/24
// Returns:   	void*
// Parameter: 	void * arg
//************************************
void* tMODBUSTCP_SLAVE_WORK(void* arg)
{
#define TASK_NAME_LENGTH	32
#define THREAD_NUM_LENGTH	4

	int sock;
	int* sock_accept;
	pthread_t tMODBUSTCP_SLAVE_RW_ID = 0;
	char name[TASK_NAME_LENGTH] = { 0 };
	char Thread_Num[THREAD_NUM_LENGTH] = { 0 };
	unsigned char Count = 0;

	printf("the Kernel_%s is %d\r\n", "tMODBUSTCP_SLAVE_WORK_ID", syscall(SYS_gettid));			//< duan20200610
	//< 初始化TCP服务器端设置
	if (false == TCP_Sever_Init(&sock, MODBUSTCP_PORT, 0, nullptr))
	{ 
		printf("Modbus-TCP sever-sock init wrong\r\n"); 
		while (1); 
	}
	sock_accept = (int*)calloc(1, sizeof(int));
	while (1)
	{
		//< 等待被连接
		if (false == TCP_Sever_Accept(&sock, sock_accept, 5))
		{
			continue;
		}

		//< 线程名称动态生成
		memset(Thread_Num, 0, TASK_NAME_LENGTH * sizeof(char));
		memset(name, 0, TASK_NAME_LENGTH * sizeof(char));
		strcpy(name, "tMODBUSTCP_SLAVE_RW_ID_Num");
		Int2String(Count++, Thread_Num, 10);
		if (Count > 254)
			Count = 0;
		strcat(name, Thread_Num);

		//< 启动工作线程
		THREAD_CREATE_FAILED(Thread_Create(name, &tMODBUSTCP_SLAVE_RW_ID, NULL, SCHED_POLICY, 89, true, tMODBUSTCP_SLAVE_Work_Thread, CONTROL_CORE, sock_accept));
		sock_accept = (int*)calloc(1, sizeof(int));//< 连接成功后开辟套接字供下一个设备连接
	}

#undef TASK_NAME_LENGTH
#undef THREAD_NUM_LENGTH
}

//************************************
// Method:    	tMODBUSTCP_SLAVE_Work_Thread	MODBUS-485从站工作线程
// Programmer:  lww
// Time:		2019/2/25
// Returns:   	void *
// Parameter: 	void * arg
//************************************
void *tMODBUSTCP_SLAVE_Work_Thread(void* arg)
{
#define PCK_MAXNUM	300
#define MAX_LINK_NUM	20						//< 最大级联的卡件数量

	int* sock = NULL; //对端套接字
	int i = 0;
	NAME(MODBUSTCP_SLAVE)* base = NULL;
	char tmp_char = 0;
	unsigned char SendData[PCK_MAXNUM] = { 0 };
	unsigned char RecvData[PCK_MAXNUM] = { 0 };
	short SendCount = 0;
	short RecvCount = 0;
	unsigned short StartAddr = 0;
	unsigned short NumOfData = 0;
	NAME(MODBUSTCP_SLAVE)* Card_Pt[MAX_LINK_NUM] = { 0 };	//< 级联的卡件的信息结构体指针数组
	unsigned char Link_Num = 0;								//< 级联的卡件数量
	bool flag = true;										//< 判断卡件级联数量是否正确的标志位
	NAME(MODBUSTCP_SLAVE)** Base_Pt = NULL;   //数据所在卡件地址的指针	  （在那个卡件）
	unsigned short* Pos_Pt = NULL; //数据所在卡件的具体通道的地址   （在卡件的那个通道）
	NAME(MODBUSTCP_SLAVE)* Base_Pos = NULL;
	int position = 0;

	printf("the Kernel_%s is %d\r\n", "tMODBUSTCP_SLAVE_Work_Thread_ID", syscall(SYS_gettid));			//< duan20200610
	//< 初始化参数
	sock = (int*)arg;

	while (1)
	{
		//< duan20200317 注释
		//if (SYS_Role != Master_Alone_Role && SYS_Role != Master_Twins_Role)
		//{
		//	//< TCP_SLAVE_Clean_Buffer(sock);				//< duan2019/11/14添加内容 目的在于清空socket接收缓冲区
		//	//< duan20200313 第一次测试
		//	memset(RecvData, 0, sizeof(RecvData));
		//	TCP_Recv(sock, RecvData, 200, 10000);			//< duan20200315修改  2000ms
		//	continue;
		//}

		//< 检查网口状态，网口状态为未连接时，关闭套接字，关闭线程
		if (false == Connect_Status_Judge(sock[0]))
		{
			close(sock[0]);
			return NULL;
		}

		//< duan20200317 添加
		if (SYS_Role != Master_Alone_Role && SYS_Role != Master_Twins_Role)			//< duan20200330注释该if条件
		{
			//< TCP_SLAVE_Clean_Buffer(sock);				//< duan2019/11/14添加内容 目的在于清空socket接收缓冲区
			//< duan20200313 第一次测试
			/*memset(RecvData, 0, sizeof(RecvData));
			TCP_Recv(sock, RecvData, 200, 10000);*/			//< duan20200315修改  2000ms

			//< duan20200323 第二次测试
			//< 等待接收第一个字节
			if (TCP_Recv(sock, &tmp_char, 1, MODBUSTCP_SLAVE_List_Par.Wait_ResponseMSG_MaxTime) < 1)
			{
				continue;//< 超时时间内未接收到第一个字节，则开始下一次循环
			}
			RecvCount = 0;
			SendCount = 0;
			memset(SendData, 0, sizeof(SendData));			//< 初始化接收请求报文数组
			memset(RecvData, 0, sizeof(RecvData));			//< 初始化发送回复报文数组
			RecvData[RecvCount++] = tmp_char;
			while (TCP_Recv(sock, &tmp_char, 1, MODBUSTCP_SLAVE_List_Par.Recv_MaxTime) == 1) { RecvData[RecvCount++] = tmp_char; }		//< 接收剩余信息
			if (RecvCount > 300)
			{
				printf("ERROR-the modbus_slave recv count beyond 300\r\n");
			}
			//< 组织回复报文
			for (i = 0; i < 8; i++)
			{
				SendData[SendCount++] = RecvData[i];
			}
			//异常码:从站设备忙		
			SendData[7] = (unsigned char)(SendData[7] + 0x80);		//< 异常功能码
			SendData[SendCount++] = 0x06;							//< 从站设备忙

			SendData[4] = HIGH_CHAR(SendCount - 6);
			SendData[5] = LOW_CHAR(SendCount - 6);

			if (TCP_Send(sock, SendData, SendCount, MODBUSTCP_SLAVE_List_Par.Send_MaxTime) < SendCount) 
				printf("Send response msg wrong\r\n"); 

			continue;
		}

		//< 等待接收第一个字节
		if (TCP_Recv(sock, &tmp_char, 1, MODBUSTCP_SLAVE_List_Par.Wait_ResponseMSG_MaxTime) < 1)
		{
			continue;//< 超时时间内未接收到第一个字节，则开始下一次循环
		}

		RecvCount = 0;
		SendCount = 0;
		memset(SendData, 0, sizeof(SendData));			//< 初始化接收请求报文数组
		memset(RecvData, 0, sizeof(RecvData));			//< 初始化发送回复报文数组

		RecvData[RecvCount++] = tmp_char;

		while (1)
		{
#define QUIT(name)	{\
	printf(name);\
	break;\
}
//异常码：非法的数据地址
#define WRONG_CODE2_DEAL	{\
	printf("The address master visit from %d to %d beyond the limit we set in funcode%d\r\n", StartAddr, (StartAddr + NumOfData), RecvData[7]);\
	SendData[7] = (unsigned char)(SendData[7] + 0x80);\
	SendData[SendCount++] = (unsigned char)0x02;\
}
//异常码：非法的数据值
#define WRONG_CODE3_DEAL(name)	{\
	printf(name);\
	printf(" in funcode%d\r\n", RecvData[7]);\
	SendData[7] = (unsigned char)(SendData[7] + 0x80);\
	SendData[SendCount++] = (unsigned char)0x03;\
}
#define ISDOUBLE	(Card_Pt[0]->Sta.Is_Double)
#define CHANNEL_SEARCH_INIT	{\
	Base_Pt = (NAME(MODBUSTCP_SLAVE) * *)calloc(NumOfData, sizeof(NAME(MODBUSTCP_SLAVE)*));\
	Pos_Pt = (unsigned short*)calloc(NumOfData, sizeof(unsigned short));\
}

			//< duan20200326第三次测试
			/*if (SYS_Role == Master_Alone_Role || SYS_Role == Master_Twins_Role)
				printf("ERROR-the SYS_Role is illeagle change\r\n");*/

			while (TCP_Recv(sock, &tmp_char, 1, MODBUSTCP_SLAVE_List_Par.Recv_MaxTime) == 1) { RecvData[RecvCount++] = tmp_char; }		//< 接收剩余信息
			//< duan20200511 测试
			if (RecvCount > 300)
			{
				printf("ERROR-the modbus_slave recv count beyond 300\r\n");
			}
			
			//< 初步判断接收到的数据量是否正确
			if (RecvCount < 10) { QUIT("The byte num modbus-tcp-slave recv is wrong1\r\n"); }
			//< 判断协议标识符是否正确
			if (RecvData[2] != 0x00 || RecvData[3] != 0x00) { QUIT("The symbol of modbus-tcp-slave is wrong\r\n"); }
			//< 根据长度域精确判断接收到的数据量是否正确
			if((((RecvData[4] << 8) | RecvData[5]) + 6) != RecvCount) { QUIT("The byte num modbus-tcp-slave recv is wrong1\r\n"); }
			
			//< 判断该模件地址下是否存在卡件，根据级联号顺序将该模件地址下存在的卡件的信息结构体指针依次放入指针数组中
			Link_Num = 0;
			memset(Card_Pt, NULL, sizeof(Card_Pt));
			for (i = 0; i < Card_List[TYPE(MODBUSTCP_SLAVE)].iCount; i++)		//< duan 遍历所有MODBUSTCP_SLAVE类型的卡件
			{
				base = (NAME(MODBUSTCP_SLAVE)*)SearchAt((List_Base_t*)(Card_List[TYPE(MODBUSTCP_SLAVE)].ppData[0]), i);
				if (base != NULL)
				{
					if (base->Sta.ModuleAddr == RecvData[6])
					{
						Card_Pt[base->Sta.Link_No - 1] = base;					//< duan 将符合要求模件地址的卡件放入指针数组中
						Link_Num++;
					}
				}
			}
			if (Link_Num == 0) { QUIT("The msg don't belong to these module\r\n"); }	//< 模件地址

			//< 判断级联卡件的数量是否正确
			flag = true;
			for (i = 0; i < Link_Num; i++)
			{
				if (Card_Pt[i] == NULL)
				{
					flag = false;
					break;
				}
			}
			if (flag == false) { QUIT("Unit Number is wrong, please check\r\n"); }

			//< 组织回复报文
			for (i = 0; i < 8; i++)
			{
				SendData[SendCount++] = RecvData[i];
			}
			StartAddr = (unsigned short)((RecvData[8] << 8) | RecvData[9]);	//< 起始地址

			if (RecvData[7] == 0x01)
			{
				NumOfData = (unsigned short)((RecvData[10] << 8) | RecvData[11]);									//< 访问通道的个数
				CHANNEL_SEARCH_INIT;
				if (NumOfData < 0x0001 || NumOfData > 0x07D0) { WRONG_CODE3_DEAL("The number of channel to visit beyond the limit"); }

				else if (MODBUSTCP_SLAVE_Channel_Search(Card_Pt, Base_Pt, Pos_Pt, DI_CHA, StartAddr, NumOfData, ISDOUBLE, Link_Num) == false) { WRONG_CODE2_DEAL; }
				else
				{
					SendData[SendCount++] = (unsigned char)(NumOfData / 8 + (((NumOfData % 8) == 0) ? 0 : 1));		//< 返回的字节数
					for (i = 0; i < NumOfData; i++)
					{
						SendData[SendCount + i / 8] = (unsigned char)(SendData[SendCount + i / 8] | (Base_Pt[i]->Base.DIChannel[Pos_Pt[i]].Sta_Property.CurOut_Value << (i % 8)));
					}
					SendCount = (short)(SendCount + SendData[8]);
				}
			}
			else if (RecvData[7] == 0x02)
			{
				NumOfData = (unsigned short)((RecvData[10] << 8) | RecvData[11]);									//< 访问通道的个数
				CHANNEL_SEARCH_INIT;
				if (NumOfData < 0x0001 || NumOfData > 0x07D0) { WRONG_CODE3_DEAL("The number of channel to visit beyond the limit"); }
				else if (MODBUSTCP_SLAVE_Channel_Search(Card_Pt, Base_Pt, Pos_Pt, DO_CHA, StartAddr, NumOfData, ISDOUBLE, Link_Num) == false) { WRONG_CODE2_DEAL; }
				else
				{
					SendData[SendCount++] = (unsigned char)(NumOfData / 8 + (((NumOfData % 8) == 0) ? 0 : 1));		//< 返回的字节数
					for (i = 0; i < NumOfData; i++)
					{
						SendData[SendCount + i / 8] = (unsigned char)(SendData[SendCount + i / 8] | (Base_Pt[i]->Base.DOChannel[Pos_Pt[i]].Sta_Property.CurOut_Value << (i % 8)));
					}
					SendCount = (short)(SendCount + SendData[8]);
				}
			}
			else if (RecvData[7] == 0x03)
			{
				NumOfData = (unsigned short)((RecvData[10] << 8) | RecvData[11]);									//< 访问通道的个数
				CHANNEL_SEARCH_INIT;
				if (NumOfData < 0x0001 || NumOfData > 0x007D) { WRONG_CODE3_DEAL("The number of channel to visit beyond the limit"); }
				else if (MODBUSTCP_SLAVE_Channel_Search(Card_Pt, Base_Pt, Pos_Pt, AI_CHA, StartAddr, NumOfData, ISDOUBLE, Link_Num) == false) { WRONG_CODE2_DEAL; }
				else
				{
					SendData[SendCount++] = (unsigned char)(2 * NumOfData);
					if (ISDOUBLE == true)
						for (i = 0; i < NumOfData; i++)
						{
							int tmp_int;
							tmp_int = *((int*) & (Base_Pt[i]->Base.AIChannel[Pos_Pt[i]].Sta_Property.CurOut_Value));
							if (((StartAddr + i - Base_Pt[i]->Par.StartAddrOf_AI) % 2) == 0)//< 决定取float的前两个字节还是后两个字节
							{
								SendData[SendCount + 2 * i + 0] = (unsigned char)((tmp_int >> 24) & 0xFF);
								SendData[SendCount + 2 * i + 1] = (unsigned char)((tmp_int >> 16) & 0xFF);
							}
							else
							{
								SendData[SendCount + 2 * i + 0] = (unsigned char)((tmp_int >> 8) & 0xFF);
								SendData[SendCount + 2 * i + 1] = (unsigned char)(tmp_int & 0xFF);
							}								
						}
					else
						for (i = 0; i < NumOfData; i++)
						{
							unsigned short tmp_ushort;
							tmp_ushort = (unsigned short)Base_Pt[i]->Base.AIChannel[Pos_Pt[i]].Sta_Property.CurOut_Value;
							SendData[SendCount + 2 * i + 0] = (unsigned char)((tmp_ushort >> 8) & 0xFF);
							SendData[SendCount + 2 * i + 1] = (unsigned char)(tmp_ushort & 0xFF);
						}
					SendCount = (short)(SendCount + SendData[8]);
				}
			}
			else if (RecvData[7] == 0x04)
			{
				NumOfData = (unsigned short)((RecvData[10] << 8) | RecvData[11]);									//< 访问通道的个数
				CHANNEL_SEARCH_INIT;
				if (NumOfData < 0x0001 || NumOfData > 0x007D) { WRONG_CODE3_DEAL("The number of channel to visit beyond the limit"); }
				else if (MODBUSTCP_SLAVE_Channel_Search(Card_Pt, Base_Pt, Pos_Pt, AO_CHA, StartAddr, NumOfData, ISDOUBLE, Link_Num) == false) { WRONG_CODE2_DEAL; }
				else
				{
					SendData[SendCount++] = (unsigned char)(2 * NumOfData);
					if (ISDOUBLE == true)
						for (i = 0; i < NumOfData; i++)
						{
							int tmp_int;
							tmp_int = *((int*) & (Base_Pt[i]->Base.AOChannel[Pos_Pt[i]].Sta_Property.CurOut_Value));
							if (((StartAddr + i - Base_Pt[i]->Par.StartAddrOf_AO) % 2) == 0)//< 决定取float的前两个字节还是后两个字节
							{
								SendData[SendCount + 2 * i + 0] = (unsigned char)((tmp_int >> 24) & 0xFF);
								SendData[SendCount + 2 * i + 1] = (unsigned char)((tmp_int >> 16) & 0xFF);
							}
							else
							{
								SendData[SendCount + 2 * i + 0] = (unsigned char)((tmp_int >> 8) & 0xFF);
								SendData[SendCount + 2 * i + 1] = (unsigned char)(tmp_int & 0xFF);
							}
						}
					else
						for (i = 0; i < NumOfData; i++)
						{
							unsigned short tmp_ushort;
							tmp_ushort = (unsigned short)Base_Pt[i]->Base.AOChannel[Pos_Pt[i]].Sta_Property.CurOut_Value;
							SendData[SendCount + 2 * i] = (unsigned char)((tmp_ushort >> 8) & 0xFF);//模拟量高8位    （一个模拟量占2个字节）
							SendData[SendCount + 2 * i + 1] = (unsigned char)(tmp_ushort & 0xFF);//模拟量低8位
						}
					SendCount = (short)(SendCount + SendData[8]);
				}
			}
			else if (RecvData[7] == 0x05)
			{
				unsigned short tmp_ushort;
				tmp_ushort = (unsigned short)((RecvData[10] << 8) | RecvData[11]);
				NumOfData = 1;
				CHANNEL_SEARCH_INIT;
				if (tmp_ushort != 0x0000 && tmp_ushort != 0xFF00) { WRONG_CODE3_DEAL("The value of channel is not equal to 0x0000 or 0xFF00"); }
				else if (MODBUSTCP_SLAVE_Channel_Search(Card_Pt, Base_Pt, Pos_Pt, DI_CHA, StartAddr, NumOfData, ISDOUBLE, Link_Num) == false) { WRONG_CODE2_DEAL; }
				else
				{
					SendData[SendCount++] = RecvData[8];
					SendData[SendCount++] = RecvData[9];
					SendData[SendCount++] = RecvData[10];
					SendData[SendCount++] = RecvData[11];
					if (tmp_ushort == 0x0000)
						DV_Write(&(Base_Pt[0]->Base.DIChannel[Pos_Pt[0]]), false, WRITE);
					else if (tmp_ushort == 0xFF00)
						DV_Write(&(Base_Pt[0]->Base.DIChannel[Pos_Pt[0]]), true, WRITE);
				}
			}
			else if (RecvData[7] == 0x06)
			{
				//unsigned short tmp_ushort;												//< duan 20191111 注释，只能写入无符号数
				//tmp_ushort = (unsigned short)((RecvData[10] << 8) | RecvData[11]);
				short tmp_short;															//< duan 20191111 修改，写入有符号数
				tmp_short = (short)((RecvData[10] << 8) | RecvData[11]);
				NumOfData = 1;
				CHANNEL_SEARCH_INIT;
				/*if (tmp_ushort < 0x0000 || tmp_ushort > 0xFFFF) { WRONG_CODE3_DEAL("The value of channel is not vary from 0x0000 to 0xFFFF"); }*/
				if (tmp_short < (short)0x8001 || tmp_short > (short)0x7FFF) { WRONG_CODE3_DEAL("The value of channel is not vary from -32767 to 32767"); }
				else if (MODBUSTCP_SLAVE_Channel_Search(Card_Pt, Base_Pt, Pos_Pt, AI_CHA, StartAddr, NumOfData, ISDOUBLE, Link_Num) == false) { WRONG_CODE2_DEAL; }
				else
				{
					SendData[SendCount++] = RecvData[8];
					SendData[SendCount++] = RecvData[9];
					SendData[SendCount++] = RecvData[10];
					SendData[SendCount++] = RecvData[11];
					AV_Write(&(Base_Pt[0]->Base.AIChannel[Pos_Pt[0]]), (float)tmp_short, WRITE);
				}
			}
			else if (RecvData[7] == 0x0F)
			{
				NumOfData = (unsigned short)((RecvData[10] << 8) | RecvData[11]);
				CHANNEL_SEARCH_INIT;
				if (NumOfData < 0x0001 || NumOfData > 0x07B0) { WRONG_CODE3_DEAL("The number of channel to visit beyond the limit"); }
				else if (MODBUSTCP_SLAVE_Channel_Search(Card_Pt, Base_Pt, Pos_Pt, DI_CHA, StartAddr, NumOfData, ISDOUBLE, Link_Num) == false) { WRONG_CODE2_DEAL; }
				else
				{
					SendData[SendCount++] = RecvData[8];
					SendData[SendCount++] = RecvData[9];
					SendData[SendCount++] = RecvData[10];
					SendData[SendCount++] = RecvData[11];
					for (i = 0; i < NumOfData; i++)
					{
						DV_Write(&(Base_Pt[i]->Base.DIChannel[Pos_Pt[i]]), (RecvData[13 + i / 8] & (0x01 << (i % 8))), WRITE);
					}
				}
			}
			else if (RecvData[7] == 0x10)
			{
				unsigned char Float_Byte[4];
				NumOfData = (unsigned short)((RecvData[10] << 8) | RecvData[11]);
				CHANNEL_SEARCH_INIT;
				if (NumOfData < 0x0001 || NumOfData > 0x007B) { WRONG_CODE3_DEAL("The number of channel to visit beyond the limit"); }
				else if (MODBUSTCP_SLAVE_Channel_Search(Card_Pt, Base_Pt, Pos_Pt, AI_CHA, StartAddr, NumOfData, ISDOUBLE, Link_Num) == false) { WRONG_CODE2_DEAL; }
				else
				{
					SendData[SendCount++] = RecvData[8];
					SendData[SendCount++] = RecvData[9];
					SendData[SendCount++] = RecvData[10];
					SendData[SendCount++] = RecvData[11];
					i = 0;
					if (ISDOUBLE == true)
						while(i < NumOfData)
						{
							int tmp_int;
							Base_Pos = Base_Pt[i];
							position = Pos_Pt[i];
							tmp_int = *((int*) & (Base_Pos->Base.AIChannel[position].Sta_Property.CurOut_Value));
							Float_Byte[0] = (unsigned char)((tmp_int >> 24) & 0xFF);
							Float_Byte[1] = (unsigned char)((tmp_int >> 16) & 0xFF);
							Float_Byte[2] = (unsigned char)((tmp_int >> 8) & 0xFF);
							Float_Byte[3] = (unsigned char)((tmp_int >> 0) & 0xFF);

							if (((StartAddr + i - Base_Pos->Par.StartAddrOf_AI) % 2) == 0)//< 决定取float的前两个字节还是后两个字节
							{
								Float_Byte[0] = RecvData[13 + 2 * i + 0];
								Float_Byte[1] = RecvData[13 + 2 * i + 1];
								i++;
								if (i < NumOfData)
								{
									Float_Byte[2] = RecvData[13 + 2 * i + 0];
									Float_Byte[3] = RecvData[13 + 2 * i + 1];
									i++;
								}
							}
							else
							{
								Float_Byte[2] = RecvData[13 + 2 * i + 0];
								Float_Byte[3] = RecvData[13 + 2 * i + 1];
								i++;
							}

							tmp_int = (Float_Byte[0] << 24 | Float_Byte[1] << 16 | Float_Byte[2] << 8 | Float_Byte[3]);
							AV_Write(&(Base_Pos->Base.AIChannel[position]), *((float*)&tmp_int), WRITE);
						}
					else
						for (i = 0; i < NumOfData; i++)
						{
							AV_Write(&(Base_Pt[i]->Base.AIChannel[Pos_Pt[i]]), (float)((short)(RecvData[13 + 2 * i] << 8 | RecvData[13 + 2 * i + 1])), WRITE);			//< duan 20191111修改 有符号数
						}
				}
			}
			else
			{
				printf("The msg's funcode is wrong\r\n");
				SendData[7] = (unsigned char)(SendData[7] + 0x80);
				SendData[SendCount++] = 0x01;
			}

			SendData[4] = HIGH_CHAR(SendCount - 6);
			SendData[5] = LOW_CHAR(SendCount - 6);

			if (TCP_Send(sock, SendData, SendCount, MODBUSTCP_SLAVE_List_Par.Send_MaxTime) < SendCount) { QUIT("Send response msg wrong\r\n"); }
			
			FREE_Pt(Base_Pt);
			FREE_Pt(Pos_Pt);					//< duan20200327
			
			QUIT(NULL);
				
#undef QUIT
#undef WRONG_CODE2_DEAL
#undef WRONG_CODE3_DEAL
#undef ISDOUBLE
#undef CHANNEL_SEARCH_INIT
		}
	}

#undef PCK_MAXNUM
#undef MAX_LINK_NUM
	return NULL;
}

//************************************
// Method:    	MODBUSTCP_SLAVE_Channel_Search		判断访问的数据区间是否越界
// Programmer:  lww
// Time:		2019/8/15
// Returns:   	bool								true-成功；false-失败
// Parameter: 	Channel_type_e type					通道类型
// Parameter: 	unsigned short StartAddr			起始地址
// Parameter: 	unsigned short NumOfData			通道数量
// Parameter: 	unsigned short Total_Num			该通道上的数据点总数量
// Parameter: 	bool Is_Double						是否为双字MODBUS
//************************************
bool MODBUSTCP_SLAVE_Channel_Search(Channel_type_e type, unsigned short StartAddr, unsigned short NumOfData, unsigned short Total_Num, bool Is_Double)
{
	if (type == DI_CHA || type == DO_CHA)
	{
		if ((StartAddr >= 0) && ((unsigned int)(StartAddr + NumOfData - 1) < Total_Num))
			return true;
		else
			return false;
	}
	if (type == AI_CHA || type == AO_CHA)
	{
		if ((StartAddr >= 0) && ((unsigned int)(StartAddr + NumOfData - 1) < (Total_Num * ((Is_Double == true) ? 2 : 1))))
			return true;
		else
			return false;
	}
	return false;
}

//************************************
// Method:    	Pos_Search							根据级联情况寻找规定位置的数据点在卡件中的存储位置
// Programmer:  lww
// Time:		2019/8/15
// Returns:   	int									返回在卡件中的存储位置
// Parameter: 	NAME(MODBUSTCP_SLAVE)* Card_Pt[]	级联的卡件信息结构体数组
// Parameter: 	NAME(MODBUSTCP_SLAVE)* * base		存放当前搜索的数据点所位于的卡件信息结构体指针
// Parameter: 	unsigned short Num_Sum[]			级联卡件通道数量累计值数组
// Parameter: 	unsigned short position				数据点位置
// Parameter: 	unsigned char Link_Num				级联卡件的总数量
//************************************
unsigned short MODBUSTCP_SLAVE_Pos_Search(NAME(MODBUSTCP_SLAVE)* Card_Pt[], NAME(MODBUSTCP_SLAVE)** base, unsigned short Num_Sum[], unsigned short position, unsigned char Link_Num)
{
	int i = 0;
	unsigned short pos;
	if (position < Num_Sum[0])
	{
		pos = position;
		base[0] = Card_Pt[0];
		return pos;
	}
	for (i = 1; i < Link_Num; i++)
	{
		if (position >= Num_Sum[i - 1] && position < Num_Sum[i])
		{
			pos = position - Num_Sum[i - 1];
			base[0] = Card_Pt[i];
			return pos;
		}
	}
	return Num_Sum[i - 1];
}

//************************************
// Method:    	CHANGE_CARD_LIST_PAR		修改该类型卡件属性
// Programmer:  lww
// Time:		2019/4/4
// Returns:   	int							读取字节长度计数值
// Parameter: 	Card_Base_t* arg			指定卡件属性结构体的指针
// Parameter: 	void** Data					存放数据包当前指针位置的地址
//************************************
int CHANGE_CARD_LIST_PAR(MODBUSTCP_SLAVE)(Card_Base_t* arg, void** Data)
{
	int _iLen = 0;
	MEMREAD((*CLIST_PAR(MODBUSTCP_SLAVE)), Data[0]);
	return _iLen;
}

//************************************
// Method:    	MODBUS485_SLAVE_Channel_Search		寻找主站访问的地址是否越界
// Programmer:  lww
// Time:		2019/9/16
// Returns:   	bool								true-成功；false-失败
// Parameter: 	NAME(MODBUS485_SLAVE)* Card_Pt[]	级联的卡件信息结构体数组
// Parameter: 	Channel_type_e type					通道类型
// Parameter: 	unsigned short StartAddr			起始地址
// Parameter: 	unsigned short NumOfData			通道数量
// Parameter: 	bool Is_Double						是否为双字
// Parameter: 	unsigned char Link_Num				级联的卡件的数量
//************************************
bool MODBUSTCP_SLAVE_Channel_Search(NAME(MODBUSTCP_SLAVE)* Card_Pt[], NAME(MODBUSTCP_SLAVE)** Base_Pt, unsigned short* Pos_Pt, Channel_type_e type, unsigned short StartAddr, unsigned short NumOfData, bool Is_Double, unsigned char Link_Num)
{
	int i, j;
	bool Exist_Flag = false;
	for (i = StartAddr; i < StartAddr + NumOfData; i++)
	{
		Exist_Flag = false;
		for (j = 0; j < Link_Num; j++)
		{
			if (type == DI_CHA && ((i >= Card_Pt[j]->Par.StartAddrOf_DI) && (i < Card_Pt[j]->Par.StartAddrOf_DI + Card_Pt[j]->Base.IO_Num.DI_Num)))
			{
				Pos_Pt[i - StartAddr] = i - Card_Pt[j]->Par.StartAddrOf_DI;			//< duan 0917记录主站访问的数据通道在该张卡件通道的位置
				Exist_Flag = true;
			}

			if (type == DO_CHA && ((i >= Card_Pt[j]->Par.StartAddrOf_DO) && (i < Card_Pt[j]->Par.StartAddrOf_DO + Card_Pt[j]->Base.IO_Num.DO_Num)))
			{
				Pos_Pt[i - StartAddr] = i - Card_Pt[j]->Par.StartAddrOf_DO;
				Exist_Flag = true;
			}

			if (type == AI_CHA && ((i >= Card_Pt[j]->Par.StartAddrOf_AI) && (i < Card_Pt[j]->Par.StartAddrOf_AI + (Card_Pt[j]->Base.IO_Num.AI_Num * ((Is_Double == true) ? 2 : 1)))))
			{
				Pos_Pt[i - StartAddr] = (i - Card_Pt[j]->Par.StartAddrOf_AI) / ((Is_Double == true) ? 2 : 1);
				Exist_Flag = true;
			}

			if (type == AO_CHA && ((i >= Card_Pt[j]->Par.StartAddrOf_AO) && (i < Card_Pt[j]->Par.StartAddrOf_AO + (Card_Pt[j]->Base.IO_Num.AO_Num * ((Is_Double == true) ? 2 : 1)))))
			{
				Pos_Pt[i - StartAddr] = (i - Card_Pt[j]->Par.StartAddrOf_AO) / ((Is_Double == true) ? 2 : 1);
				Exist_Flag = true;
			}

			if (Exist_Flag == true)
			{
				Base_Pt[i - StartAddr] = Card_Pt[j];			//< duan0917 记录主站访问的每一个数据通道所在卡件的位置
				break;
			}
		}
		if (Exist_Flag == false)
			return false;
	}
	return true;
}
//************************************
// Method:    	CHANGE_CARD_PAR				在线修改卡件参数函数
// Programmer:  lww
// Time:		2018/11/16
// Returns:   	int							读取字节长度计数值
// Parameter: 	Card_Base_t* arg			指定卡件属性结构体的指针
// Parameter: 	void** Data					存放数据包当前指针位置的地址
//************************************
int CHANGE_CARD_PAR(MODBUSTCP_SLAVE)(Card_Base_t* arg, void** Data)
{
	int _iLen = 0;
	MEMREAD(((NAME(MODBUSTCP_SLAVE)*)arg)->Par, Data[0]);
	return _iLen;
}

//************************************
// Method:    	INIT_STAPAR					初始化卡件不可调参数结构体
// Programmer:  lww
// Time:		2018/11/16
// Returns:   	int							读取字节长度计数值
// Parameter: 	Card_Base_t* arg			指定卡件属性结构体的指针
// Parameter: 	void** Data					存放数据包当前指针位置的地址
//************************************
int INIT_CARD_STA(MODBUSTCP_SLAVE)(Card_Base_t* arg, void** Data)
{
	int _iLen = 0;
	MEMREAD(((NAME(MODBUSTCP_SLAVE)*)arg)->Sta, Data[0]);
	return _iLen;
}

